﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using Microsoft.Phone.Tasks;

namespace DIS.WindowsPhone.Toolkit.Controls
{
    /// <summary>
    /// Represents an Ad that displays the Microsoft Ad Control and falls back to a user specified banner if no ads to display
    /// </summary>
    public class AdControl : Control
    {
        Microsoft.Advertising.Mobile.UI.AdControl adControl1;
        Image image1;
        string deferredApplicationID = null;
        string deferredAdUnitID = null;
        public AdControl()
        {
            DefaultStyleKey = typeof(AdControl);
        }

        void msftAdControl_ErrorOccurred(object sender, Microsoft.Advertising.AdErrorEventArgs e)
        {
            if (e.Error != null)
            {
                adControl1.Visibility = System.Windows.Visibility.Collapsed;
                image1.Visibility = System.Windows.Visibility.Visible;
                ChooseRandomApplicationBanner();
            }
        }

        void Image_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            MarketplaceDetailTask task = new MarketplaceDetailTask();
            task.ContentIdentifier = image1.Tag.ToString();
            task.Show();
        }

        void ChooseRandomApplicationBanner()
        {
            if (ApplicationBanners == null || ApplicationBanners.Count == 0)
            {
                this.Visibility = System.Windows.Visibility.Collapsed;
                return;
            }

            Random random = new Random((int)DateTime.Now.Ticks);
            int index = random.Next(0, ApplicationBanners.Count);
            image1.Source = new BitmapImage(ApplicationBanners[index].AppBannerUri);
            image1.Tag = ApplicationBanners[index].ApplicationID;
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            adControl1 = GetTemplateChild("msftAdControl") as Microsoft.Advertising.Mobile.UI.AdControl;
            image1 = GetTemplateChild("image1") as Image;

            adControl1.ErrorOccurred += msftAdControl_ErrorOccurred;
            image1.Tap += Image_Tap;

            if (!String.IsNullOrWhiteSpace(deferredAdUnitID))
            {
                adControl1.AdUnitId = deferredAdUnitID;
                deferredAdUnitID = null;
            }
            if (!String.IsNullOrWhiteSpace(deferredApplicationID))
            {
                adControl1.ApplicationId = deferredApplicationID;
                deferredApplicationID = null;
            }
        }

        #region AdUnitID
        public static readonly DependencyProperty AdUnitProperty =
            DependencyProperty.Register("AdUnitID", typeof(string), typeof(AdControl), new PropertyMetadata(null, AdUnit_PropertyChangedCallback));

        private static void AdUnit_PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            AdControl control = ((AdControl)d);
            if (control.adControl1 != null)
                control.adControl1.AdUnitId = e.NewValue.ToString();
            else
                control.deferredAdUnitID = e.NewValue.ToString();
        }

        /// <summary>
        /// <para>Gets or sets the ad unit identifier for the Microsoft <c>AdControl</c> instance.</para>
        /// <para>This value is provided to the publisher when the publisher creates an <c>AdUnit</c> in pubCenter. See the Publisher Onboarding Guide for more information</para>
        /// </summary>
        /// <remarks>
        /// <para>This property can only be set when the <c>AdControl</c> is instantiated by using the default constructor</para>
        /// <para>Once set, this property cannot be modified</para>
        /// </remarks>
        public string AdUnitID
        {
            get
            {
                return (string)GetValue(AdUnitProperty);
            }
            set
            {
                SetValue(AdUnitProperty, value);
            }
        }
        #endregion AdUnitID

        #region ApplicationBanners

        public static readonly DependencyProperty ApplicationBannersProperty =
            DependencyProperty.Register("ApplicationBanners", typeof(List<ApplicationBanner>), typeof(AdControl),
            new PropertyMetadata(null));

        /// <summary>
        /// The list of <c>ApplicationBanner</c> used when the <c>AdControl</c> object doesn't have any ads to show.
        /// </summary>
        public List<ApplicationBanner> ApplicationBanners
        {
            get
            {
                return (List<ApplicationBanner>)GetValue(ApplicationBannersProperty);
            }
            set
            {
                SetValue(ApplicationBannersProperty, value);
            }
        }
        #endregion ApplicationBanners

        #region ApplicationID
        public static readonly DependencyProperty ApplicationIDProperty =
            DependencyProperty.Register("ApplicationID", typeof(string), typeof(AdControl), new PropertyMetadata(null, ApplicationID_PropertyChangedCallback));

        private static void ApplicationID_PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            AdControl control = ((AdControl)d);
            if (control.adControl1 != null)
                control.adControl1.ApplicationId = e.NewValue.ToString();
            else
                control.deferredApplicationID = e.NewValue.ToString();
        }

        /// <summary>
        /// The application ID of the app. This value is provided to you when you register the app with pubCenter
        /// </summary>
        /// <remarks>
        /// <para>Only one value for the application ID can be used within an app.</para>
        /// <para>If more than one value for the <c>ApplicationID</c> is used in different <c>AdControl</c> objects that are in the app, some controls will not receive ads and will raise an <c>ErrorOccurred</c> event.</para>
        /// </remarks>
        public string ApplicationID
        {
            get
            {
                return (string)GetValue(ApplicationIDProperty);
            }
            set
            {
                SetValue(ApplicationIDProperty, value);
            }
        }
        #endregion ApplicationID
    }
}
